home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Chat & Communication / Digsby build 37 / digsby_setup.exe / lib / pyxmpp / jabber / clientstream.pyo (.txt) < prev    next >
Python Compiled Bytecode  |  2008-10-13  |  12KB  |  385 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. __revision__ = '$Id: clientstream.py 680 2008-08-21 06:24:42Z jajcus $'
  5. __docformat__ = 'restructuredtext en'
  6. from hashlib import sha1
  7. import logging
  8. from pyxmpp.iq import Iq
  9. from pyxmpp.utils import to_utf8, from_utf8
  10. from pyxmpp.jid import JID
  11. from pyxmpp.clientstream import ClientStream
  12. from pyxmpp.jabber.register import Register
  13. from pyxmpp.exceptions import ClientStreamError, LegacyAuthenticationError, RegistrationError
  14.  
  15. class LegacyClientStream(ClientStream):
  16.     
  17.     def __init__(self, jid, password = None, server = None, port = 5222, auth_methods = ('sasl:DIGEST-MD5', 'digest'), tls_settings = None, keepalive = 0, owner = None):
  18.         (self.authenticated, self.available_auth_methods, self.auth_stanza, self.peer_authenticated, self.auth_method_used, self.registration_callback, self.registration_form, self._LegacyClientStream__register) = (None, None, None, None, None, None, None, None)
  19.         ClientStream.__init__(self, jid, password, server, port, auth_methods, tls_settings, keepalive, owner)
  20.         self._LegacyClientStream__logger = logging.getLogger('pyxmpp.jabber.LegacyClientStream')
  21.  
  22.     
  23.     def _reset(self):
  24.         ClientStream._reset(self)
  25.         self.available_auth_methods = None
  26.         self.auth_stanza = None
  27.         self.registration_callback = None
  28.  
  29.     
  30.     def _post_connect(self):
  31.         if not self.initiator:
  32.             if 'plain' in self.auth_methods or 'digest' in self.auth_methods:
  33.                 self.set_iq_get_handler('query', 'jabber:iq:auth', self.auth_in_stage1)
  34.                 self.set_iq_set_handler('query', 'jabber:iq:auth', self.auth_in_stage2)
  35.             
  36.         elif self.registration_callback:
  37.             iq = Iq(stanza_type = 'get')
  38.             iq.set_content(Register())
  39.             self.set_response_handlers(iq, self.registration_form_received, self.registration_error)
  40.             self.send(iq)
  41.             return None
  42.         
  43.         ClientStream._post_connect(self)
  44.  
  45.     
  46.     def _post_auth(self):
  47.         ClientStream._post_auth(self)
  48.         if not self.initiator:
  49.             self.unset_iq_get_handler('query', 'jabber:iq:auth')
  50.             self.unset_iq_set_handler('query', 'jabber:iq:auth')
  51.         
  52.  
  53.     
  54.     def _try_auth(self):
  55.         if self.authenticated:
  56.             self._LegacyClientStream__logger.debug('try_auth: already authenticated')
  57.             return None
  58.         
  59.         self._LegacyClientStream__logger.debug('trying auth: %r' % (self._auth_methods_left,))
  60.         if not self._auth_methods_left:
  61.             raise LegacyAuthenticationError, 'No allowed authentication methods available'
  62.         
  63.         method = self._auth_methods_left[0]
  64.         if method.startswith('sasl:'):
  65.             return ClientStream._try_auth(self)
  66.         elif method not in ('plain', 'digest'):
  67.             self._auth_methods_left.pop(0)
  68.             self._LegacyClientStream__logger.debug('Skipping unknown auth method: %s' % method)
  69.             return self._try_auth()
  70.         elif self.available_auth_methods is not None:
  71.             self._auth_methods_left.pop(0)
  72.             if method in self.available_auth_methods:
  73.                 self.auth_method_used = method
  74.                 if method == 'digest':
  75.                     self._digest_auth_stage2(self.auth_stanza)
  76.                 else:
  77.                     self._plain_auth_stage2(self.auth_stanza)
  78.                 self.auth_stanza = None
  79.                 return None
  80.             else:
  81.                 self._LegacyClientStream__logger.debug('Skipping unavailable auth method: %s' % method)
  82.                 return self._try_auth()
  83.         else:
  84.             self._auth_stage1()
  85.  
  86.     
  87.     def auth_in_stage1(self, stanza):
  88.         self.lock.acquire()
  89.         
  90.         try:
  91.             if 'plain' not in self.auth_methods and 'digest' not in self.auth_methods:
  92.                 iq = stanza.make_error_response('not-allowed')
  93.                 self.send(iq)
  94.                 return None
  95.             
  96.             iq = stanza.make_result_response()
  97.             q = iq.new_query('jabber:iq:auth')
  98.             q.newChild(None, 'username', None)
  99.             q.newChild(None, 'resource', None)
  100.             if 'plain' in self.auth_methods:
  101.                 q.newChild(None, 'password', None)
  102.             
  103.             if 'digest' in self.auth_methods:
  104.                 q.newChild(None, 'digest', None)
  105.             
  106.             self.send(iq)
  107.             iq.free()
  108.         finally:
  109.             self.lock.release()
  110.  
  111.  
  112.     
  113.     def auth_in_stage2(self, stanza):
  114.         self.lock.acquire()
  115.         
  116.         try:
  117.             if 'plain' not in self.auth_methods and 'digest' not in self.auth_methods:
  118.                 iq = stanza.make_error_response('not-allowed')
  119.                 self.send(iq)
  120.                 return None
  121.             
  122.             username = stanza.xpath_eval('a:query/a:username', {
  123.                 'a': 'jabber:iq:auth' })
  124.             if username:
  125.                 username = from_utf8(username[0].getContent())
  126.             
  127.             resource = stanza.xpath_eval('a:query/a:resource', {
  128.                 'a': 'jabber:iq:auth' })
  129.             if resource:
  130.                 resource = from_utf8(resource[0].getContent())
  131.             
  132.             if not username or not resource:
  133.                 self._LegacyClientStream__logger.debug('No username or resource found in auth request')
  134.                 iq = stanza.make_error_response('bad-request')
  135.                 self.send(iq)
  136.                 return None
  137.             
  138.             if stanza.xpath_eval('a:query/a:password', {
  139.                 'a': 'jabber:iq:auth' }):
  140.                 if 'plain' not in self.auth_methods:
  141.                     iq = stanza.make_error_response('not-allowed')
  142.                     self.send(iq)
  143.                     return None
  144.                 else:
  145.                     return self._plain_auth_in_stage2(username, resource, stanza)
  146.             
  147.             if stanza.xpath_eval('a:query/a:digest', {
  148.                 'a': 'jabber:iq:auth' }):
  149.                 if 'plain' not in self.auth_methods:
  150.                     iq = stanza.make_error_response('not-allowed')
  151.                     self.send(iq)
  152.                     return None
  153.                 else:
  154.                     return self._digest_auth_in_stage2(username, resource, stanza)
  155.         finally:
  156.             self.lock.release()
  157.  
  158.  
  159.     
  160.     def _auth_stage1(self):
  161.         iq = Iq(stanza_type = 'get')
  162.         q = iq.new_query('jabber:iq:auth')
  163.         q.newTextChild(None, 'username', to_utf8(self.my_jid.node))
  164.         q.newTextChild(None, 'resource', to_utf8(self.my_jid.resource))
  165.         self.send(iq)
  166.         self.set_response_handlers(iq, self.auth_stage2, self.auth_error, self.auth_timeout, timeout = 60)
  167.         iq.free()
  168.  
  169.     
  170.     def auth_timeout(self):
  171.         self.lock.acquire()
  172.         
  173.         try:
  174.             self._LegacyClientStream__logger.debug('Timeout while waiting for jabber:iq:auth result')
  175.             if self._auth_methods_left:
  176.                 self._auth_methods_left.pop(0)
  177.         finally:
  178.             self.lock.release()
  179.  
  180.  
  181.     
  182.     def auth_error(self, stanza):
  183.         self.lock.acquire()
  184.         
  185.         try:
  186.             err = stanza.get_error()
  187.             ae = err.xpath_eval('e:*', {
  188.                 'e': 'jabber:iq:auth:error' })
  189.             if ae:
  190.                 ae = ae[0].name
  191.             else:
  192.                 ae = err.get_condition().name
  193.             raise LegacyAuthenticationError, 'Authentication error condition: %s' % (ae,)
  194.         finally:
  195.             self.lock.release()
  196.  
  197.  
  198.     
  199.     def auth_stage2(self, stanza):
  200.         self.lock.acquire()
  201.         
  202.         try:
  203.             self._LegacyClientStream__logger.debug('Procesing auth response...')
  204.             self.available_auth_methods = []
  205.             if stanza.xpath_eval('a:query/a:digest', {
  206.                 'a': 'jabber:iq:auth' }) and self.stream_id:
  207.                 self.available_auth_methods.append('digest')
  208.             
  209.             if stanza.xpath_eval('a:query/a:password', {
  210.                 'a': 'jabber:iq:auth' }):
  211.                 self.available_auth_methods.append('plain')
  212.             
  213.             self.auth_stanza = stanza.copy()
  214.             self._try_auth()
  215.         finally:
  216.             self.lock.release()
  217.  
  218.  
  219.     
  220.     def _plain_auth_stage2(self, _unused):
  221.         iq = Iq(stanza_type = 'set')
  222.         q = iq.new_query('jabber:iq:auth')
  223.         q.newTextChild(None, 'username', to_utf8(self.my_jid.node))
  224.         q.newTextChild(None, 'resource', to_utf8(self.my_jid.resource))
  225.         q.newTextChild(None, 'password', to_utf8(self.password))
  226.         self.send(iq)
  227.         self.set_response_handlers(iq, self.auth_finish, self.auth_error)
  228.         iq.free()
  229.  
  230.     
  231.     def _plain_auth_in_stage2(self, username, _unused, stanza):
  232.         password = stanza.xpath_eval('a:query/a:password', {
  233.             'a': 'jabber:iq:auth' })
  234.         if password:
  235.             password = from_utf8(password[0].getContent())
  236.         
  237.         if not password:
  238.             self._LegacyClientStream__logger.debug('No password found in plain auth request')
  239.             iq = stanza.make_error_response('bad-request')
  240.             self.send(iq)
  241.             return None
  242.         
  243.         if self.check_password(username, password):
  244.             iq = stanza.make_result_response()
  245.             self.send(iq)
  246.             self.peer_authenticated = True
  247.             self.auth_method_used = 'plain'
  248.             self.state_change('authorized', self.peer)
  249.             self._post_auth()
  250.         else:
  251.             self._LegacyClientStream__logger.debug('Plain auth failed')
  252.             iq = stanza.make_error_response('bad-request')
  253.             e = iq.get_error()
  254.             e.add_custom_condition('jabber:iq:auth:error', 'user-unauthorized')
  255.             self.send(iq)
  256.  
  257.     
  258.     def _digest_auth_stage2(self, _unused):
  259.         iq = Iq(stanza_type = 'set')
  260.         q = iq.new_query('jabber:iq:auth')
  261.         q.newTextChild(None, 'username', to_utf8(self.my_jid.node))
  262.         q.newTextChild(None, 'resource', to_utf8(self.my_jid.resource))
  263.         digest = sha1(to_utf8(self.stream_id) + to_utf8(self.password)).hexdigest()
  264.         q.newTextChild(None, 'digest', digest)
  265.         self.send(iq)
  266.         self.set_response_handlers(iq, self.auth_finish, self.auth_error)
  267.         iq.free()
  268.  
  269.     
  270.     def _digest_auth_in_stage2(self, username, _unused, stanza):
  271.         digest = stanza.xpath_eval('a:query/a:digest', {
  272.             'a': 'jabber:iq:auth' })
  273.         if digest:
  274.             digest = digest[0].getContent()
  275.         
  276.         if not digest:
  277.             self._LegacyClientStream__logger.debug('No digest found in digest auth request')
  278.             iq = stanza.make_error_response('bad-request')
  279.             self.send(iq)
  280.             return None
  281.         
  282.         (password, pwformat) = self.get_password(username)
  283.         if not password or pwformat != 'plain':
  284.             iq = stanza.make_error_response('bad-request')
  285.             e = iq.get_error()
  286.             e.add_custom_condition('jabber:iq:auth:error', 'user-unauthorized')
  287.             self.send(iq)
  288.             return None
  289.         
  290.         mydigest = sha1(to_utf8(self.stream_id) + to_utf8(password)).hexdigest()
  291.         if mydigest == digest:
  292.             iq = stanza.make_result_response()
  293.             self.send(iq)
  294.             self.peer_authenticated = True
  295.             self.auth_method_used = 'digest'
  296.             self.state_change('authorized', self.peer)
  297.             self._post_auth()
  298.         else:
  299.             self._LegacyClientStream__logger.debug('Digest auth failed: %r != %r' % (digest, mydigest))
  300.             iq = stanza.make_error_response('bad-request')
  301.             e = iq.get_error()
  302.             e.add_custom_condition('jabber:iq:auth:error', 'user-unauthorized')
  303.             self.send(iq)
  304.  
  305.     
  306.     def auth_finish(self, _unused):
  307.         self.lock.acquire()
  308.         
  309.         try:
  310.             self._LegacyClientStream__logger.debug('Authenticated')
  311.             self.authenticated = True
  312.             self.state_change('authorized', self.my_jid)
  313.             self._post_auth()
  314.         finally:
  315.             self.lock.release()
  316.  
  317.  
  318.     
  319.     def registration_error(self, stanza):
  320.         self.lock.acquire()
  321.         
  322.         try:
  323.             err = stanza.get_error()
  324.             ae = err.xpath_eval('e:*', {
  325.                 'e': 'jabber:iq:auth:error' })
  326.             if ae:
  327.                 ae = ae[0].name
  328.             else:
  329.                 ae = err.get_condition().name
  330.             raise RegistrationError, 'Authentication error condition: %s' % (ae,)
  331.         finally:
  332.             self.lock.release()
  333.  
  334.  
  335.     
  336.     def registration_form_received(self, stanza):
  337.         self.lock.acquire()
  338.         
  339.         try:
  340.             self._LegacyClientStream__register = Register(stanza.get_query())
  341.             self.registration_callback(stanza, self._LegacyClientStream__register.get_form())
  342.         finally:
  343.             self.lock.release()
  344.  
  345.  
  346.     
  347.     def submit_registration_form(self, form):
  348.         self.lock.acquire()
  349.         
  350.         try:
  351.             if form and form.type != 'cancel':
  352.                 self.registration_form = form
  353.                 iq = Iq(stanza_type = 'set')
  354.                 iq.set_content(self._LegacyClientStream__register.submit_form(form))
  355.                 self.set_response_handlers(iq, self.registration_success, self.registration_error)
  356.                 self.send(iq)
  357.             else:
  358.                 self._LegacyClientStream__register = None
  359.         finally:
  360.             self.lock.release()
  361.  
  362.  
  363.     
  364.     def registration_success(self, stanza):
  365.         _unused = stanza
  366.         self.lock.acquire()
  367.         
  368.         try:
  369.             self.state_change('registered', self.registration_form)
  370.             if 'FORM_TYPE' in self.registration_form and self.registration_form['FORM_TYPE'].value == 'jabber:iq:register':
  371.                 if 'username' in self.registration_form:
  372.                     self.my_jid = JID(self.registration_form['username'].value, self.my_jid.domain, self.my_jid.resource)
  373.                 
  374.                 if 'password' in self.registration_form:
  375.                     self.password = self.registration_form['password'].value
  376.                 
  377.             
  378.             self.registration_callback = None
  379.             self._post_connect()
  380.         finally:
  381.             self.lock.release()
  382.  
  383.  
  384.  
  385.